#include <memory>
#include <vector>
#include "Server.hpp"

// 函数名为Handler更具有标志性，而Func比较平凡
std::string Handler(const std::string &message)
{
    std::string ret = "server get a meeeage: ";
    ret += message;
    std::cout << ret << std::endl;
    return ret;
}

void usage(const char *str)
{
    std::cout << "usage: \n\t";
    std::cout << str << " port[1024+]\n"
              << std::endl; // 输出内容最后可加一个\n换行，这样更美观
}

bool CheckSafe(const std::string &cmd)
{
    std::vector<std::string> v = {
        "rm",
        "cp",
        "unlink",
        "uninstall"};

    // for(auto &it : v)
    // {
    //     if(it == cmd)
    //         return false;
    // }

    // 在字符串中可能是夹带的，而不仅仅只有该词出现才返回false
    for (auto &word : v)
    {
        if (cmd.find(word) != std::string::npos)
            return false;
    }

    return true;
}

std::string ExecuteCmd(const std::string &cmd)
{
    if (!CheckSafe(cmd))
    {
        // std::cout << "bad operator" << std::endl;
        // return "";
        return "bad operator";
    }

    FILE *fd = popen(cmd.c_str(), "r");
    if (fd == nullptr)
    {
        perror("popen");
        // return "";
        return "error"; // 直接返回error而不返回空，否则可能不知晓出错
    }
    char buff[BUFF_SIZE * 4];
    // memset(buff, 0, BUFF_SIZE);
    // if(fgets(buff, BUFF_SIZE, fd) == nullptr)
    // {
    //     perror("fgets");
    //     return "";
    // }
    // return buff;
    std::string ret;
    // 需要用循环逐次获取，否则获取的数据可能不完整
    while (true)
    {
        char *check = fgets(buff, sizeof(buff), fd);
        if (check == nullptr)
            break;
        ret += buff;
        // std::cout << ret << std::endl;
    }
    pclose(fd); // 记得关闭
    return ret;
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        usage(argv[0]);

        // return 0;
        exit(0); // 不是预期的结果。可以用exit退出
    }

    uint16_t server_port = std::stoi(argv[1]);

    // 本程序只是启动Server，无需使用socket套接字

    std::unique_ptr<Server> up(new Server(server_port));
    up->Init();
    // up->Run(Handler);
    //  up->Run(ExecuteCmd);
    up->Run();

    return 0;
}